package com.studynotes.dev.tech.common.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.*;

/**
 * @author Liu XiaoJun
 * @description: 验证方法工具类
 * @date 2025-11-07 13:25:01
 */
public class ValidateUtil {

    private static Validator validator;

    private ValidateUtil() {
        throw new IllegalStateException("Utility class");
    }

    static {
        validator = SpringUtil.getBean(Validator.class);
    }

    /**
     * 校验对象
     * @param object        待校验对象
     * @param groups        待校验的组
     * @param <T> 数据类型
     */
    public static <T> void validateEntity(T object, Class<?>... groups) {
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(object, groups);
        buildMessage(constraintViolations);
    }

    /**
     * validateEntity
     *
     * @param object object
     * @param cls class
     * @param groups group
     * @param <V> class type
     * @param <T> class type
     */
    public static <V, T> void validateWithEntity(T object, Class<V> cls, Class<?>... groups) {
        V entity = BeanUtil.copyProperties(object, cls);
        validateEntity(entity, groups);
    }

    /**
     * validateParamter
     *
     * @param cls class type
     * @param propertyName property name
     * @param value 值
     * @param groups 验证组
     * @param <T> class type
     */
    public static <T> void validateParameter(Class<T> cls, String propertyName, Object value, Class<?>... groups) {
        Set<ConstraintViolation<T>> constraintViolations = validator.validateValue(cls, propertyName, value, groups);
        buildMessage(constraintViolations);
    }

    public static <T> void buildMessage(Set<ConstraintViolation<T>> constraintViolations) {
        if (!constraintViolations.isEmpty()) {
            List<Object> jsonList = new ArrayList<>();
            for(ConstraintViolation<T> constraint:  constraintViolations){
                Map<String, Object> jsonObject = new HashMap<>(2);
                jsonObject.put("name", constraint.getPropertyPath().toString());
                jsonObject.put("msg", constraint.getMessage());
                jsonList.add(jsonObject);
            }

            throw new ValidateException(JsonUtil.beanToJson(jsonList));
        }
    }


    /**
     * parseBindingResult
     *
     * @param bindingResult 验证结果
     * @throws ValidateException 验证消息异常
     */
    public static void parseBindingResult(BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new ValidateException(buildBindingResultMessage(bindingResult));
        }
    }

    /**
     * 组装验证消息
     *
     * @param bindingResult 验证结果
     * @return 消息
     */
    public static String buildBindingResultMessage(BindingResult bindingResult) {
        List<Object> jsonList = new ArrayList<>();
        bindingResult.getAllErrors().forEach(objectError -> {
            Map<String, Object> jsonObject = new HashMap<>(2);
            if (objectError instanceof FieldError) {
                jsonObject.put("filed", ((FieldError) objectError).getField());
            }
            jsonObject.put("msg", objectError.getDefaultMessage());
            jsonList.add(jsonObject);
        });
        return JsonUtil.beanToJson(jsonList);
    }

}
